package com.fastjrun.security.authentication.wechat;

import com.fastjrun.security.authentication.mobile.MobileConstants;
import com.fastjrun.security.properties.SecurityProperties;
import com.xkcoding.justauth.AuthRequestFactory;
import lombok.RequiredArgsConstructor;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component // 不要少了
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class WechatValidateFilter extends OncePerRequestFilter {

  private final AuthRequestFactory factory;

  @Resource private SecurityProperties securityProperties;

  @Autowired AuthenticationFailureHandler customAuthenticationFailureHandler;

  @Override
  protected void doFilterInternal(
      HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
      throws ServletException, IOException {
    // 1. 判断 请求是否为微信扫码登录结果返回，且get请求
    if (HttpMethod.GET.name().equalsIgnoreCase(request.getMethod())
        && (request
            .getRequestURI()
            .endsWith(securityProperties.getAuthentication().getCallbackWechatUrl()))) {

      try {
        // 校验验证码合法性
        validate(request);
      } catch (AuthenticationException e) {
        // 交给失败处理器进行处理异常
        customAuthenticationFailureHandler.onAuthenticationFailure(request, response, e);
        // 一定要记得结束
        return;
      }
    }

    // 放行
    filterChain.doFilter(request, response);
  }

  private void validate(HttpServletRequest request) {
    // 先获取seesion中的验证码
    String code = request.getParameter(WechatConstants.REQUEST_KEY_CODE);
    String state = request.getParameter(WechatConstants.REQUEST_KEY_STATE);
    AuthRequest authRequest = factory.get(AuthDefaultSource.WECHAT_OPEN.name());
    AuthCallback authCallback=new AuthCallback();
    authCallback.setCode(code);
    authCallback.setState(state);
    AuthResponse<AuthUser> response = authRequest.login(authCallback);

    if(response.ok()){
      AuthUser authUser=response.getData();
      // 将openid保存到session中
      request.getSession().setAttribute(WechatConstants.SESSION_KEY_OPNEID, authUser.getRawUserInfo().getString("openid"));
    }
  }
}
